home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-13 / thesrc10.zip / FILE.C < prev    next >
C/C++ Source or Header  |  1992-08-12  |  34KB  |  1,017 lines

  1. /***********************************************************************/
  2. /* FILE.C - File and view related functions.                           */
  3. /***********************************************************************/
  4. /*
  5.  * THE - The Hessling Editor. A text editor similar to VM/CMS xedit.
  6.  * Copyright (C) 1991,1992 Mark Hessling
  7.  *
  8.  * This program is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU General Public License as
  10.  * published by the Free Software Foundation; either version 2 of
  11.  * the License, or any later version.
  12.  *
  13.  * This program is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16.  * General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU General Public License
  19.  * along with this program; if not, write to:
  20.  *
  21.  *    The Free Software Foundation, Inc.
  22.  *    675 Mass Ave,
  23.  *    Cambridge, MA 02139 USA.
  24.  *
  25.  *
  26.  * If you make modifications to this software that you feel increases
  27.  * it usefulness for the rest of the community, please email the
  28.  * changes, enhancements, bug fixes as well as any and all ideas to me.
  29.  * This software is going to be maintained and enhanced as deemed
  30.  * necessary by the community.
  31.  *
  32.  * Mark Hessling                     email: M.Hessling@itc.gu.edu.au
  33.  * 36 David Road                     Phone: +61 7 849 7731
  34.  * Holland Park                      Fax:   +61 7 875 7877
  35.  * QLD 4121
  36.  * Australia
  37.  */
  38. #include <stdio.h>
  39. #include <stdlib.h>
  40.  
  41. #include "the.h"
  42. #include "directry.h"
  43.  
  44. /*#define TRACE*/
  45. /*-------------------------- external data ----------------------------*/
  46. extern LINE *next_line,*curr_line;
  47. extern VIEW_DETAILS *vd_current,*vd_first,*vd_mark;
  48. extern char current_screen;
  49. extern SCREEN_DETAILS screen[MAX_SCREENS];        /* screen structures */
  50. extern WINDOW *foot,*error_window;
  51. extern char error_on_screen;
  52. extern char number_of_views;
  53. extern char number_of_files;
  54. extern char display_screens;                      /* number of screens */
  55. extern unsigned char *rec;
  56. extern unsigned short rec_len;
  57. extern unsigned char *cmd_rec;
  58. extern unsigned short cmd_rec_len;
  59. extern unsigned char in_profile;    /* indicates if processing profile */
  60. extern unsigned char mode_insert;        /* defines insert mode toggle */
  61. extern char file_disposition;
  62. extern struct stat stat_buf;
  63. extern unsigned char temp_cmd[150];
  64. extern unsigned char dir_filename[MAX_FILE_NAME+1];
  65. extern unsigned char dir_pathname[MAX_FILE_NAME+1];
  66. extern unsigned char sp_path[MAX_FILE_NAME+1] ;
  67. extern unsigned char sp_fname[MAX_FILE_NAME+1] ;
  68. extern unsigned char dir_path[MAX_FILE_NAME+1] ;    /* for dir and ls commands */
  69. /*---------------------- function definitions -------------------------*/
  70. #ifdef PROTO
  71. VIEW_DETAILS * find_file(unsigned char *,unsigned char *);
  72. #else
  73. VIEW_DETAILS * find_file();
  74. #endif
  75. /***********************************************************************/
  76. #ifdef PROTO
  77. short get_file(unsigned char *filename)
  78. #else
  79. short get_file(filename)
  80. unsigned char *filename;
  81. #endif
  82. /***********************************************************************/
  83. {
  84. /*-------------------------- external data ----------------------------*/
  85.  extern unsigned char CMD_LINEx;
  86.  extern unsigned char ERROR_ROWx;
  87.  extern unsigned char TAB_ROWx;
  88.  extern unsigned char TAB_ONx;
  89.  extern unsigned char SCALE_ROWx;
  90.  extern unsigned char SCALE_ONx;
  91.  extern unsigned char PRE_ONx;
  92.  extern unsigned char PRE_LEFTx;
  93.  extern unsigned char CURRENT_ROW_POSx;
  94.  extern unsigned char STAYx;
  95.  extern unsigned char CASE_Ex;
  96.  extern unsigned char CASE_Lx;
  97.  extern unsigned char CASE_Cx;
  98.  extern unsigned char TABO_ONx;
  99.  extern unsigned char TABO_Nx;
  100.  extern unsigned char TABSx;
  101. /*--------------------------- local data ------------------------------*/
  102.  char fno;
  103.  LINE *curr;
  104.  char work_filename[MAX_FILE_NAME+1] ;
  105.  VIEW_DETAILS *save_current_view,*found_file;
  106.  int rc;
  107. /*--------------------------- processing ------------------------------*/
  108. #ifdef TRACE
  109.  trace_function("file.c:    get_file");
  110. #endif
  111. /*---------------------------------------------------------------------*/
  112. /* Split the filename supplied into directory and filename parts.      */
  113. /* This is done before allocating a new current_file number.           */
  114. /*---------------------------------------------------------------------*/
  115.  
  116.  if (splitpath(filename) == ERROR)
  117.    {
  118.     display_error(10,filename);
  119. #ifdef TRACE
  120.     trace_return();
  121. #endif
  122.     return(ERROR);
  123.    }
  124. /*---------------------------------------------------------------------*/
  125. /* If the filename portion of the splithpath is empty, then we are     */
  126. /* editting a directory. So create the new file with the appropriate OS*/
  127. /* command and set the filename to DIR.DIR.                            */
  128. /*---------------------------------------------------------------------*/
  129.  if (strcmp(sp_fname,"") == 0)
  130.    {
  131.     if (read_directory() == ERROR)
  132.        {
  133. #ifdef TRACE
  134.         trace_return();
  135. #endif
  136.         return(ERROR);
  137.        }
  138.     strcpy(sp_path,dir_pathname);
  139.     strcpy(sp_fname,dir_filename);
  140.    }
  141. /*---------------------------------------------------------------------*/
  142. /* If this is the first file to be editted, don't check to see if the  */
  143. /* file is already in the ring. Obvious hey!                           */
  144. /*---------------------------------------------------------------------*/
  145.  if (CURRENT_VIEW == (VIEW_DETAILS *)NULL)     /* no files in ring yet */
  146.    {
  147.     if (defaults_for_first_file() == ERROR)
  148.       {
  149. #ifdef TRACE
  150.        trace_return();
  151. #endif
  152.        return(ERROR);
  153.       }
  154.    }
  155.  else
  156.    {
  157. /*---------------------------------------------------------------------*/
  158. /* Here we should check if we already have the file to be editted in   */
  159. /* the ring. If the file is there and it is DIR.DIR, QQUIT out of it   */
  160. /* otherwise set the current pointer to it and exit.                   */
  161. /*---------------------------------------------------------------------*/
  162.     save_current_view = CURRENT_VIEW;
  163.     if ((found_file = find_file(sp_path,sp_fname)) != (VIEW_DETAILS *)NULL)
  164.       {
  165.        CURRENT_VIEW = found_file;
  166.        if (strcmp(CURRENT_FILE->fname,dir_filename) == 0
  167.        &&  strcmp(CURRENT_FILE->fpath,dir_pathname) == 0)
  168.          {
  169.           Qquit("");
  170.           if (CURRENT_VIEW == (VIEW_DETAILS *)NULL)
  171.              rc = defaults_for_first_file();
  172.           else
  173.              rc = defaults_for_other_files();
  174.           if (rc == ERROR)
  175.             {
  176. #ifdef TRACE
  177.              trace_return();
  178. #endif
  179.              return(ERROR);
  180.             }
  181.          }
  182.        else
  183.           {
  184. #ifdef TRACE
  185.            trace_return();
  186. #endif
  187.            return(OK);
  188.           }
  189.       }
  190.     else
  191.       {
  192.        CURRENT_VIEW = save_current_view;
  193.        if (defaults_for_other_files() == ERROR)
  194.          {
  195. #ifdef TRACE
  196.           trace_return();
  197. #endif
  198.           return(ERROR);
  199.          }
  200.       }
  201.     }
  202. /*---------------------------------------------------------------------*/
  203. /* Allocate memory to file pointer.                                    */
  204. /*---------------------------------------------------------------------*/
  205.  if ((CURRENT_FILE = (FILE_DETAILS *)memMalloc(sizeof(FILE_DETAILS),"current_file")) == NULL)
  206.    {
  207.     free_view_memory();
  208.     display_error(30,"");
  209. #ifdef TRACE
  210.     trace_return();
  211. #endif
  212.     return(ERROR);
  213.    }
  214. /*---------------------------------------------------------------------*/
  215. /* Set up default file attributes.                                     */
  216. /*---------------------------------------------------------------------*/
  217.  default_file_attributes();
  218. /*---------------------------------------------------------------------*/
  219. /* Copy the filename and path strings split up at the start of the     */
  220. /* function.                                                           */
  221. /*---------------------------------------------------------------------*/
  222.  if ((CURRENT_FILE->fname = (unsigned char *)memMalloc(strlen(sp_fname)+1,"get_file name")) == NULL)
  223.    {
  224.     free_view_memory();
  225.     display_error(30,"");
  226. #ifdef TRACE
  227.     trace_return();
  228. #endif
  229.     return(ERROR);
  230.    }
  231.  if ((CURRENT_FILE->fpath = (unsigned char *)memMalloc(strlen(sp_path)+1,"get_file path")) == NULL)
  232.    {
  233.     free_view_memory();
  234.     display_error(30,"");
  235. #ifdef TRACE
  236.     trace_return();
  237. #endif
  238.     return(ERROR);
  239.    }
  240.  strcpy(CURRENT_FILE->fname,sp_fname);
  241.  strcpy(CURRENT_FILE->fpath,sp_path);
  242.  
  243.  strcpy(work_filename,sp_path);
  244.  strcat(work_filename,sp_fname);
  245. /*---------------------------------------------------------------------*/
  246. /* If the file is not readable, then display error.                    */
  247. /*---------------------------------------------------------------------*/
  248.  if (!file_readable(work_filename))
  249.    {
  250.     display_error(8,work_filename);
  251.     free_view_memory();
  252. #ifdef TRACE
  253.     trace_return();
  254. #endif
  255.     return(ERROR);
  256.    }
  257. /*---------------------------------------------------------------------*/
  258. /* If the file doesn't exist create a new one                          */
  259. /*---------------------------------------------------------------------*/
  260.  if ((CURRENT_FILE->fp = fopen(work_filename,"r")) == NULL)
  261.    {
  262.     file_disposition = FILE_NEW;
  263.     if (!in_profile)
  264.        display_error(0,"New file...");
  265.    }
  266.  else
  267.     if (file_writable(work_filename))
  268.        file_disposition = FILE_NORMAL;
  269.     else
  270.       {
  271.        file_disposition = FILE_READONLY;
  272.        if (!in_profile)
  273.           display_error(0,"File is read-only...");
  274.       }
  275. /*---------------------------------------------------------------------*/
  276. /* first_line is set to "Top of FIle"                                  */
  277. /*---------------------------------------------------------------------*/
  278.  
  279.  if ((CURRENT_FILE->first_line = add_line(CURRENT_FILE->first_line,NULL,TOP_OF_FILE,
  280.      strlen(TOP_OF_FILE))) == NULL)
  281.    {
  282.     free_view_memory();
  283. #ifdef TRACE
  284.     trace_return();
  285. #endif
  286.     return(ERROR);
  287.    }
  288.  
  289.  curr = CURRENT_FILE->first_line;
  290.  
  291.  CURRENT_FILE->number_lines = 0L;
  292.  if (file_disposition != FILE_NEW)
  293.    {
  294.     stat(work_filename,&stat_buf);
  295.     CURRENT_FILE->fmode = stat_buf.st_mode;
  296.     if ((curr = read_file(CURRENT_FILE->fp,curr,work_filename)) == NULL)
  297.       {
  298.        free_view_memory();
  299. #ifdef TRACE
  300.        trace_return();
  301. #endif
  302.        return(ERROR);
  303.       }
  304.    }
  305.  else
  306.     CURRENT_FILE->fmode = FMODE;
  307. /*---------------------------------------------------------------------*/
  308. /* last line is set to "Bottom of File"                                */
  309. /*---------------------------------------------------------------------*/
  310.  
  311.  if (add_line(CURRENT_FILE->first_line,curr,BOTTOM_OF_FILE,
  312.      strlen(BOTTOM_OF_FILE)) == NULL)
  313.    {
  314.     free_view_memory();
  315. #ifdef TRACE
  316.     trace_return();
  317. #endif
  318.     return(ERROR);
  319.    }
  320.  
  321.  if (file_disposition != FILE_NEW)
  322.     fclose(CURRENT_FILE->fp);
  323.  
  324.  number_of_files++;
  325.  
  326. #ifdef TRACE
  327.  trace_return();
  328. #endif
  329.  return(OK);
  330. }
  331. /***********************************************************************/
  332. #ifdef PROTO
  333. LINE *read_file(FILE *fp,LINE *curr,unsigned char *filename)
  334. #else
  335. LINE *read_file(fp,curr,filename)
  336. FILE *fp;
  337. LINE *curr;
  338. unsigned char *filename;
  339. #endif
  340. /***********************************************************************/
  341. {
  342. /*-------------------------- external data ----------------------------*/
  343.  extern unsigned char TABI_ONx;
  344.  extern unsigned char TABI_Nx;
  345. /*--------------------------- local data ------------------------------*/
  346.  register unsigned short i;
  347.  short ch;
  348.  LINE *temp;
  349. /*--------------------------- processing ------------------------------*/
  350. #ifdef TRACE
  351.  trace_function("file.c:    read_file");
  352. #endif
  353.  temp = curr;
  354.  memset(rec,' ',MAX_LINE_LENGTH);
  355.  i = 0;
  356.  while(1)
  357.   {
  358.    ch = fgetc(fp);
  359.    if (feof(fp))
  360.       break;
  361.    if (ch == '\t'&& TABI_ONx)
  362.      {
  363.       do
  364.        {
  365.         rec[i] = ' ';
  366.         i++;
  367.         if (i >= MAX_LINE_LENGTH)
  368.           {
  369.            display_error(29,"line too long");
  370. #ifdef TRACE
  371.            trace_return();
  372. #endif
  373.            return(NULL);
  374.           }
  375.        }
  376.       while ((i % TABI_Nx) != 0);
  377. /*      while (((i+1) % TABI_Nx) != 0);*/
  378.       continue;
  379.      }
  380.    if (ch == '\n')
  381.      {
  382.       rec[i] = '\0';
  383.       if ((temp = add_line(CURRENT_FILE->first_line,temp,rec,i)) == NULL)
  384.         {
  385. #ifdef TRACE
  386.          trace_return();
  387. #endif
  388.          return(NULL);
  389.         }
  390.       CURRENT_FILE->number_lines++;
  391.       i = 0;
  392.       memset(rec,' ',MAX_LINE_LENGTH);
  393.       continue;
  394.      }
  395.    if (ch == '\r')
  396.      {
  397.       rec[i] = ch;
  398.       i++;
  399.       ch = fgetc(fp);
  400.       if (feof(fp))
  401.          break;
  402.       if (ch == '\n')
  403.         {
  404.          --i;
  405.          rec[i] = '\0';
  406.          if ((temp = add_line(CURRENT_FILE->first_line,temp,rec,i)) == NULL)
  407.            {
  408. #ifdef TRACE
  409.             trace_return();
  410. #endif
  411.             return(NULL);
  412.            }
  413.          CURRENT_FILE->number_lines++;
  414.          i = 0;
  415.          memset(rec,' ',MAX_LINE_LENGTH);
  416.          continue;
  417.         }
  418.      }
  419. #ifdef SUN
  420.    if (ch > 128)
  421.        {
  422.              sprintf(rec,"Line: %d; Col: %d  '%1.1c'=%2.2X/%3.3d",
  423.                        CURRENT_FILE->number_lines+1,i+2,ch,ch,ch);
  424.              display_error(29,rec);
  425. #ifdef TRACE
  426.              trace_return();
  427. #endif
  428.              return(NULL);
  429.              break;
  430.        }
  431. #endif
  432.    rec[i] = ch;
  433.    i++;
  434.    if (i >= MAX_LINE_LENGTH)
  435.      {
  436.       sprintf(rec,"Line too long: %d",CURRENT_FILE->number_lines+1);
  437.       display_error(29,rec);
  438. #ifdef TRACE
  439.       trace_return();
  440. #endif
  441.       return(NULL);
  442.      }
  443.   }
  444. #ifdef TRACE
  445.  trace_return();
  446. #endif
  447.  return(temp);
  448. }
  449. /***********************************************************************/
  450. #ifdef PROTO
  451. short save_file(unsigned char *new_fname,char force,long in_lines,
  452.                 char append)
  453. #else
  454. short save_file(new_fname,force,in_lines,append)
  455. unsigned char *new_fname;
  456. char force,append;
  457. long in_lines;
  458. #endif
  459. /***********************************************************************/
  460. {
  461. /*--------------------------- local data ------------------------------*/
  462.  unsigned char *bak_filename;
  463.  unsigned char *write_fname;
  464.  register int i;
  465.  long j;
  466.  long num_lines=in_lines;
  467.  LINE *curr;
  468.  FILE *fp;
  469.  unsigned short col,newcol;
  470.  short off;
  471.  unsigned char c;
  472. /*--------------------------- processing ------------------------------*/
  473. #ifdef TRACE
  474.  trace_function("file.c:    save_file");
  475. #endif
  476.  if ((write_fname = (unsigned char *)memMalloc(MAX_FILE_NAME,"write_fname")) == NULL)
  477.    {
  478.     display_error(30,"");
  479. #ifdef TRACE
  480.     trace_return();
  481. #endif
  482.     return(ERROR);
  483.    }
  484. /*---------------------------------------------------------------------*/
  485. /* If a new filename is specified, use it as the old filename.         */
  486. /*---------------------------------------------------------------------*/
  487.  if (strcmp(new_fname,"") != 0)                  /* new_fname supplied */
  488.    {
  489. /*---------------------------------------------------------------------*/
  490. /* Split the supplied new filename.                                    */
  491. /*---------------------------------------------------------------------*/
  492.     if (splitpath(new_fname) == ERROR)
  493.       {
  494.        display_error(10,new_fname);
  495. #ifdef TRACE
  496.        trace_return();
  497. #endif
  498.        return(ERROR);
  499.       }
  500.     strcpy(write_fname,sp_path);
  501.     strcat(write_fname,sp_fname);
  502. /*---------------------------------------------------------------------*/
  503. /* Test to make sure that the write fname doesn't exist...             */
  504. /* ...unless we are forcing the write.                                 */
  505. /*---------------------------------------------------------------------*/
  506.     if ((!force) && file_exists(write_fname))
  507.       {
  508.        display_error(31,write_fname);
  509.        memFree(write_fname,"write_fname");
  510. #ifdef TRACE
  511.        trace_return();
  512. #endif
  513.        return(ERROR);
  514.       }
  515.    }
  516.  else
  517.    {
  518. /*---------------------------------------------------------------------*/
  519. /* Create the name of the current file.                                */
  520. /*---------------------------------------------------------------------*/
  521.     strcpy(write_fname,CURRENT_FILE->fpath);
  522.     strcat(write_fname,CURRENT_FILE->fname);
  523. /*---------------------------------------------------------------------*/
  524. /* Rename the current file to filename.bak.                            */
  525. /*---------------------------------------------------------------------*/
  526.     if ((bak_filename =
  527.            (unsigned char *)memMalloc(strlen(CURRENT_FILE->fpath)+strlen(CURRENT_FILE->fname)+5,
  528.            "bak_filename")) == NULL)
  529.       {
  530.        display_error(30,"");
  531.        memFree(write_fname,"write_fname");
  532. #ifdef TRACE
  533.        trace_return();
  534. #endif
  535.        return(ERROR);
  536.       }
  537.     new_filename(CURRENT_FILE->fpath,CURRENT_FILE->fname,bak_filename,".bak");
  538.     if (CURRENT_FILE->fp != NULL)
  539.       {
  540.        remove_file(bak_filename);
  541.        if (rename(write_fname,bak_filename) != 0)
  542.          {
  543.           display_error(8,write_fname);
  544.           memFree(write_fname,"write_fname");
  545. #ifdef TRACE
  546.           trace_return();
  547. #endif
  548.           return(ERROR);
  549.          }
  550.       }
  551.    }
  552. /*---------------------------------------------------------------------*/
  553. /* Test to make sure that we can write the file.                       */
  554. /*---------------------------------------------------------------------*/
  555.  if (!file_writable(write_fname))
  556.    {
  557.     display_error(8,write_fname);
  558.     memFree(write_fname,"write_fname");
  559. #ifdef TRACE
  560.     trace_return();
  561. #endif
  562.     return(ERROR);
  563.    }
  564. /*---------------------------------------------------------------------*/
  565. /* Ensure the file is writeable.                                       */
  566. /*---------------------------------------------------------------------*/
  567.  if (append == YES)
  568.     fp = fopen(write_fname,"ab");
  569.  else
  570.     fp = fopen(write_fname,"wb");
  571.  if (fp == NULL)
  572.    {
  573.     display_error(8,"could not open for writing");
  574.     memFree(write_fname,"write_fname");
  575. #ifdef TRACE
  576.     trace_return();
  577. #endif
  578.     return(ERROR);
  579.    }
  580. /*---------------------------------------------------------------------*/
  581. /* Determine where to start writng from in the linked list.            */
  582. /*---------------------------------------------------------------------*/
  583.  if (num_lines > 0L)   /* called from put(d) command */
  584.     curr = ll_find(CURRENT_FILE->first_line,CURRENT_VIEW->current_line);
  585.  else
  586.    {
  587.     curr = CURRENT_FILE->first_line;
  588.     num_lines = CURRENT_FILE->number_lines + 1; /* forces following for to work */
  589.    }
  590. /*---------------------------------------------------------------------*/
  591. /* Now write out the contents of the file array to the new filename.   */
  592. /*---------------------------------------------------------------------*/
  593.  for (j=0L;j<num_lines && curr->next != NULL;j++)
  594.    {
  595.     if (curr->prev != NULL)  /* not first line */
  596.       {
  597.        if (CURRENT_FILE->tabsout_on)
  598.          {
  599.           col = 0;
  600.           off = 0;
  601.           while (1)
  602.             {
  603.              newcol = col;
  604.              while ((c = next_char(curr,&off)) == ' ')
  605.                {
  606.                 newcol++;
  607.                 if ((newcol % CURRENT_FILE->tabsout_num) == 0)
  608.                   {
  609.                    fputc('\t',fp);
  610.                    col = newcol;
  611.                   }
  612.                }
  613.              for (;col<newcol;col++)
  614.                  fputc(' ',fp);
  615.              if (off == (-1))  /* end of line */
  616.                 break;
  617.              fputc(c,fp);
  618.              col++;
  619.             }
  620.          }
  621.        else
  622.           for (i=0;i<curr->length;i++)
  623.               fputc(*(curr->line+i),fp);
  624.        col = 0;
  625.        if (CURRENT_FILE->eolout == EOLOUT_LF)
  626.           fputc('\n',fp);
  627.        else
  628.          {
  629.           fputc('\r',fp);
  630.           fputc('\n',fp);
  631.          }
  632.       }
  633.     curr = curr->next;
  634.    }
  635.  fclose(fp);
  636.  if (CURRENT_FILE->fmode != 0)
  637.     chmod(write_fname,CURRENT_FILE->fmode);
  638. /*---------------------------------------------------------------------*/
  639. /* If a new filename was not supplied, free up temporary memory.       */
  640. /*---------------------------------------------------------------------*/
  641.  if (strcmp(new_fname,"") == 0)
  642.     memFree(bak_filename,"bak_filename");
  643.  memFree(write_fname,"write_fname");
  644. #ifdef TRACE
  645.  trace_return();
  646. #endif
  647.  return(OK);
  648. }
  649. /***********************************************************************/
  650. #ifdef PROTO
  651. void increment_alt(void)
  652. #else
  653. void increment_alt()
  654. #endif
  655. /***********************************************************************/
  656. {
  657. /*--------------------------- local data ------------------------------*/
  658.  register short i;
  659.  unsigned char *aus_filename;
  660. /*--------------------------- processing ------------------------------*/
  661. #ifdef TRACE
  662.  trace_function("file.c:    increment_alt");
  663. #endif
  664.  CURRENT_FILE->autosave_alt++;
  665.  CURRENT_FILE->save_alt++;
  666. /*---------------------------------------------------------------------*/
  667. /* We can now test for autosave_alt exceeding the defined limit and    */
  668. /* carry out an autosave if necessary.                                 */
  669. /*---------------------------------------------------------------------*/
  670.  if (CURRENT_FILE->autosave != 0
  671.  && CURRENT_FILE->autosave_alt >= CURRENT_FILE->autosave)
  672.    {
  673.     if ((aus_filename =
  674.        (unsigned char *)memMalloc(strlen(CURRENT_FILE->fpath)+strlen(CURRENT_FILE->fname)+5,
  675.                         "aus_filename")) == NULL)
  676.       {
  677.        display_error(30,"");
  678. #ifdef TRACE
  679.        trace_return();
  680. #endif
  681.        return;
  682.       }
  683.     new_filename(CURRENT_FILE->fpath,CURRENT_FILE->fname,aus_filename,".aus");
  684.     save_file(aus_filename,YES,0L,NO);
  685.     memFree((unsigned char *)aus_filename,"aus_filename");
  686.     CURRENT_FILE->autosave_alt = 0;
  687.    }
  688. #ifdef TRACE
  689.  trace_return();
  690. #endif
  691.  return;
  692. }
  693. /***********************************************************************/
  694. #ifdef PROTO
  695. unsigned char *new_filename(unsigned char *ofp,unsigned char *ofn,
  696.                             unsigned char *nfn,unsigned char *ext)
  697. #else
  698. unsigned char *new_filename(ofp,ofn,nfn,ext)
  699. unsigned char *ofp,*ofn,*nfn,*ext;
  700. #endif
  701. /***********************************************************************/
  702. {
  703. /*--------------------------- local data ------------------------------*/
  704.  short rc;
  705. /*--------------------------- processing ------------------------------*/
  706. #ifdef TRACE
  707.  trace_function("file.c:    new_filename");
  708. #endif
  709.  strcpy(nfn,ofp);
  710.  strcat(nfn,ofn);
  711. #ifdef DOS
  712.  rc = strzeq(nfn,'.');
  713.  if (rc != (-1))
  714.     *(nfn+rc) = '\0';
  715. #endif
  716. #ifdef OS2
  717.  if (FATFileSystem(nfn)) /* returns TRUE if FAT filesystem */
  718.    {
  719.     rc = strzeq(nfn,'.');
  720.     if (rc != (-1))
  721.        *(nfn+rc) = '\0';
  722.    }
  723. #endif
  724.  strcat(nfn,ext);
  725. #ifdef TRACE
  726. #endif
  727.  return(nfn);
  728. }
  729. /***********************************************************************/
  730. #ifdef PROTO
  731. int free_view_memory(void)
  732. #else
  733. int free_view_memory()
  734. #endif
  735. /***********************************************************************/
  736. {
  737. /*--------------------------- local data ------------------------------*/
  738.  char save_current_screen;
  739.  short original_number_of_files=number_of_files;
  740. /*--------------------------- processing ------------------------------*/
  741. #ifdef TRACE
  742.  trace_function("file.c:    free_view_memory");
  743. #endif
  744.  if (--CURRENT_FILE->file_views == 0)
  745.     free_file_memory();
  746. /*---------------------------------------------------------------------*/
  747. /* If the marked block is within the current view, unset the variables.*/
  748. /*---------------------------------------------------------------------*/
  749.  if (MARK_VIEW == CURRENT_VIEW)
  750.     MARK_VIEW = (VIEW_DETAILS *)NULL;
  751. /*---------------------------------------------------------------------*/
  752. /* Delete the windows associated with the current view.                */
  753. /* Only do this if we are running interactively.                       */
  754. /*---------------------------------------------------------------------*/
  755.  if (!in_profile && CURRENT_WINDOW_MAIN != (WINDOW *)NULL)
  756.    {
  757.     if (CURRENT_VIEW->prefix_on)
  758.        delwin(CURRENT_WINDOW_PREFIX);
  759.     delwin(CURRENT_WINDOW_MAIN);
  760.     delwin(CURRENT_WINDOW_COMMAND);
  761.     delwin(CURRENT_WINDOW_ARROW);
  762.     delwin(CURRENT_WINDOW_IDLINE);
  763.    }
  764.  if ((CURRENT_VIEW = vll_del(vd_first,CURRENT_VIEW,DIRECTION_FORWARD)) == (VIEW_DETAILS *)NULL)
  765.     vd_first = (VIEW_DETAILS *)NULL;
  766.  
  767.  number_of_views--;
  768.  
  769. /*---------------------------------------------------------------------*/
  770. /* The following procedures are only carried out when the number of    */
  771. /* screens is > 1.                                                     */
  772. /*---------------------------------------------------------------------*/
  773.  if (display_screens > 1)
  774.    {
  775. /*---------------------------------------------------------------------*/
  776. /* +---+---+     +---+---+                  +---+---+     +---+---+    */
  777. /* | a | b |     | a | a |         or       | a | b |  c  | a | a |    */
  778. /* |   |   | --> |   |   |                  |   |   |     |   |   |    */
  779. /* |   |qq |     |   |   |                  |   |qq |     |   |   |    */
  780. /* +---+---+     +---+---+                  +---+---+     +---+---+    */
  781. /* number_of_files > 1                                                 */
  782. /*---------------------------------------------------------------------*/
  783.     if (original_number_of_files > 1 && OTHER_SCREEN.screen_view != (VIEW_DETAILS *)NULL)
  784.        if (CURRENT_SCREEN.screen_view->file_for_view !=
  785.            OTHER_SCREEN.screen_view->file_for_view)
  786.          {
  787.           if (defaults_for_other_files() == ERROR)
  788.             {
  789. #ifdef TRACE
  790.              trace_return();
  791. #endif
  792.              return(ERROR);
  793.             }
  794.           CURRENT_FILE = OTHER_SCREEN.screen_view->file_for_view;
  795.           CURRENT_FILE->file_views++;
  796.           set_up_windows();
  797.           CURRENT_SCREEN.screen_view = CURRENT_VIEW;
  798. /*        repaint_screen(); */
  799.          }
  800.        else
  801. /*---------------------------------------------------------------------*/
  802. /* +---+---+     +---+---+                  +---+---+     +---+---+    */
  803. /* | a | a |  b  | b | b |         or       | a | a | b c | b | b |    */
  804. /* |   |   | --> |   |   |                  |   |   |     |   |   |    */
  805. /* |   |qq |     |   |   |                  |   |qq |     |   |   |    */
  806. /* +---+---+     +---+---+                  +---+---+     +---+---+    */
  807. /* number_of_files > 1                                                 */
  808. /*---------------------------------------------------------------------*/
  809.          {
  810.          }
  811. /*---------------------------------------------------------------------*/
  812. /* +---+---+                                                           */
  813. /* | a | a |                                                           */
  814. /* |   |   | --> exit                                                  */
  815. /* |qq |   |                                                           */
  816. /* +---+---+                                                           */
  817. /* number_of_files = 1                                                 */
  818. /*---------------------------------------------------------------------*/
  819.     if (original_number_of_files == 1 && OTHER_SCREEN.screen_view != (VIEW_DETAILS *)NULL)
  820.        if (CURRENT_SCREEN.screen_view->file_for_view ==
  821.            OTHER_SCREEN.screen_view->file_for_view)
  822.           free_view_memory();
  823.    }
  824.  
  825.  if (number_of_views > 0)
  826.    {
  827.     pre_process_line(CURRENT_VIEW->focus_line);
  828.     show_page();
  829.     if (CURRENT_VIEW->prefix_on)
  830.        touchwin(CURRENT_WINDOW_PREFIX);
  831.     touchwin(CURRENT_WINDOW_COMMAND);
  832.     touchwin(CURRENT_WINDOW_MAIN);
  833.     touchwin(CURRENT_WINDOW);
  834.     show_heading(0);
  835.    }
  836. #ifdef TRACE
  837.  trace_return();
  838. #endif
  839.  return(OK);
  840. }
  841. /***********************************************************************/
  842. #ifdef PROTO
  843. int free_file_memory(void)
  844. #else
  845. int free_file_memory()
  846. #endif
  847. /***********************************************************************/
  848. {
  849. /*--------------------------- local data ------------------------------*/
  850.  LINE *curr;
  851.  register int i;
  852. /*--------------------------- processing ------------------------------*/
  853. #ifdef TRACE
  854.  trace_function("file.c:    free_file_memory");
  855. #endif
  856.  if (CURRENT_FILE->fname != NULL)
  857.    {
  858.     memFree(CURRENT_FILE->fname,CURRENT_FILE->fname);
  859.     CURRENT_FILE->fname = (unsigned char *)NULL;
  860.    }
  861.  if (CURRENT_FILE->fpath != NULL)
  862.    {
  863.     memFree(CURRENT_FILE->fpath,CURRENT_FILE->fpath);
  864.     CURRENT_FILE->fpath = (unsigned char *)NULL;
  865.    }
  866.  ll_free(CURRENT_FILE->first_line);
  867.  if (CURRENT_FILE != NULL)
  868.    {
  869.     memFree(CURRENT_FILE,"current file");
  870.     CURRENT_FILE = (FILE_DETAILS *)NULL;
  871.    }
  872.  
  873.  number_of_files--;
  874.  
  875. #ifdef TRACE
  876.  trace_return();
  877. #endif
  878.  return(OK);
  879. }
  880. /***********************************************************************/
  881. #ifdef PROTO
  882. int read_directory(void)
  883. #else
  884. int read_directory()
  885. #endif
  886. /***********************************************************************/
  887. {
  888. /*--------------------------- local data ------------------------------*/
  889.  struct dirfile *dpfirst=NULL,*dplast=NULL,*dp;
  890.  char str_attr[11];
  891.  char str_date[10];
  892.  char str_time[6];
  893. #ifdef UNIX
  894.  struct tm *timp;
  895. #endif
  896.  int rc;
  897.  FILE *fp;
  898. /*--------------------------- processing ------------------------------*/
  899. #ifdef TRACE
  900.  trace_function("file.c:    read_directory");
  901. #endif
  902. /*---------------------------------------------------------------------*/
  903. /* dir_path is set up here so that subsequent sos_edit commands can use*/
  904. /* the directory path as a prefix to the edit files filename.          */
  905. /*---------------------------------------------------------------------*/
  906.  strcpy(dir_path,sp_path);
  907. /*---------------------------------------------------------------------*/
  908. /* Get all file info for the selected files into structure. If no file */
  909. /* name specified, force it to '*'.                                    */
  910. /*---------------------------------------------------------------------*/
  911.  if (strcmp(sp_fname,"") == 0)
  912.     rc = getfiles(sp_path,"*",&dpfirst,&dplast);
  913.  else
  914.     rc = getfiles(sp_path,sp_fname,&dpfirst,&dplast);
  915.  if (rc != 0)
  916.    {
  917.     display_error(rc,sp_path);
  918. #ifdef TRACE
  919.     trace_return();
  920. #endif
  921.     return(ERROR);
  922.    }
  923.  if (dpfirst == dplast)
  924.    {
  925.     display_error(9,sp_path);
  926. #ifdef TRACE
  927.     trace_return();
  928. #endif
  929.     return(ERROR);
  930.    }
  931. /*---------------------------------------------------------------------*/
  932. /* sort the array of file structures.                                  */
  933. /*---------------------------------------------------------------------*/
  934.  qsort(dpfirst,dplast - dpfirst,sizeof(struct dirfile),fcomp);
  935. /*---------------------------------------------------------------------*/
  936. /* open the DIR.DIR file for output, overwriting any previous data     */
  937. /*---------------------------------------------------------------------*/
  938.  strcpy(temp_cmd,dir_pathname);
  939.  strcat(temp_cmd,dir_filename);
  940.  if ((fp = fopen(temp_cmd,"w")) == NULL)
  941.    {
  942.     display_error(8,sp_path);
  943. #ifdef TRACE
  944.     trace_return();
  945. #endif
  946.     return(ERROR);
  947.    }
  948. /*---------------------------------------------------------------------*/
  949. /* write out the formatted contents of the file structures.            */
  950. /*---------------------------------------------------------------------*/
  951.  for (dp=dpfirst;dp<dplast;dp++)
  952.     {
  953. #ifdef UNIX
  954.      timp = localtime(&(dp->ftime));
  955. #endif
  956.      fprintf(fp,"%s ",file_attrs(dp->fattr,str_attr));
  957.      fprintf(fp,"%8ld ",dp->fsize);
  958.      fprintf(fp,"%s ",file_date(D_NAME,str_date));
  959.      fprintf(fp,"%s ",file_time(T_NAME,str_time));
  960.      fprintf(fp,"%s\n",dp->fname);
  961.      free(dp->fname);
  962.     }
  963.  free(dpfirst);
  964.  fclose(fp);
  965.  
  966. #ifdef TRACE
  967.  trace_return();
  968. #endif
  969.  return(OK);
  970. }
  971. /***********************************************************************/
  972. #ifdef PROTO
  973. VIEW_DETAILS * find_file(unsigned char *fp,unsigned char *fn)
  974. #else
  975. VIEW_DETAILS * find_file(fp,fn)
  976. unsigned char *fp,*fn;
  977. #endif
  978. /***********************************************************************/
  979. {
  980. /*--------------------------- local data ------------------------------*/
  981.  VIEW_DETAILS *save_current_view,*found_file;
  982. /*--------------------------- processing ------------------------------*/
  983. #ifdef TRACE
  984.  trace_function("file.c:    find_file");
  985. #endif
  986. /*---------------------------------------------------------------------*/
  987. /* dir_path is set up here so that subsequent sos_edit commands can use*/
  988. /* the directory path as a prefix to the edit files filename.          */
  989. /*---------------------------------------------------------------------*/
  990.  save_current_view = CURRENT_VIEW;
  991.  CURRENT_VIEW = vd_first;
  992.  while(CURRENT_VIEW != (VIEW_DETAILS *)NULL)
  993.    {
  994. #ifdef UNIX
  995.     if (strcmp(CURRENT_FILE->fname,fn) == 0
  996.     &&  strcmp(CURRENT_FILE->fpath,fp) == 0)
  997. #else
  998.     if (memcmpi(CURRENT_FILE->fname,fn,max(strlen(CURRENT_FILE->fname),strlen(fn))) == 0
  999.     &&  memcmpi(CURRENT_FILE->fpath,fp,max(strlen(CURRENT_FILE->fpath),strlen(fp))) == 0)
  1000. #endif
  1001.       {
  1002. #ifdef TRACE
  1003.        trace_return();
  1004. #endif
  1005.        found_file = CURRENT_VIEW;
  1006.        CURRENT_VIEW = save_current_view;
  1007.        return(found_file);
  1008.       }
  1009.     CURRENT_VIEW = CURRENT_VIEW->next;
  1010.    }
  1011. #ifdef TRACE
  1012.  trace_return();
  1013. #endif
  1014.  CURRENT_VIEW = save_current_view;
  1015.  return((VIEW_DETAILS *)NULL);
  1016. }
  1017.